using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using SemWeb;
using SemWeb.Inference;
using SemWeb.Query;

namespace SemWeb85Test
{
    // This example demonstrates general reasoning with
    // the Euler engine based on Jos De Roo's Euler proof
    // mechanism.  The example is based on the "graph"
    // example from Euler.

    public class EulerTest
    {
        public static void Test3()
        {
            string needsLocation = "http://localhost:81/ontologies/2007/02/Test/needs.n3";
            string testLocation = "http://localhost:81/ontologies/2007/02/Test/test.n3";
            string rulesLocation = @"c:\Users\andrew.matthews\Documents\MyOntologies\2007\02\Test\rules.n3";
            MemoryStore store = new MemoryStore();
            store.Import(N3Reader.LoadFromUri(new Uri(needsLocation)));
            store.Import(N3Reader.LoadFromUri(new Uri(rulesLocation)));
            store.Import(N3Reader.LoadFromUri(new Uri(testLocation)));
//            Euler engine = new Euler(new N3Reader(File.OpenText(rulesLocation)));
//            RDFS engine2 = new RDFS(new N3Reader(File.OpenText(rulesLocation)));
//            store.AddReasoner(engine);

            string sparqlQuery = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
                                       + "PREFIX n: <http://localhost:81/ontologies/2007/02/Test/needs.n3#>\n"
                                       + "PREFIX t: <http://localhost:81/ontologies/2007/02/Test/test.n3#>\n"
                                       + "SELECT ?location WHERE {\n"
//                                       + "?location rdf:type n:Location.\n "
                                       + "?location n:isNear t:H1 . }";

            Sparql query = new Sparql(sparqlQuery);
            query.Run(store, Console.Out);
            Console.WriteLine("done");

        }
        public static void Test2()
        {
            string needsLocation = "http://localhost:81/ontologies/2007/02/Test/needs.n3";
            string testLocation = "http://localhost:81/ontologies/2007/02/Test/test.n3";
            string rulesLocation = @"c:\Users\andrew.matthews\Documents\MyOntologies\2007\02\Test\rules.n3";
            string rdfQueryLocation = @"c:\Users\andrew.matthews\Documents\MyOntologies\2007\02\Test\rdfquery.n3";
            string queryLocation = "http://localhost:81/ontologies/2007/02/Test/query.n3";
            string needsBase = needsLocation + "#";
            string needs = needsBase + "needs";
            string mightSelect = needsBase + "mightSelect";
            N3Writer n3w = new N3Writer(Console.Out);

            Entity hotel = new Entity("#H1");
            Entity location = new Entity("#L1");
            Entity location2 = new Entity("#L2");
            string isNear = "needs.n3#" + "isNear";

            MemoryStore store = new MemoryStore();
            store.Import(N3Reader.LoadFromUri(new Uri(needsLocation)));
            store.Import(N3Reader.LoadFromUri(new Uri(testLocation)));
            Euler engine = new Euler(new N3Reader(File.OpenText(rulesLocation)));
            RDFS engine2 = new RDFS(new N3Reader(File.OpenText(rulesLocation)));
            store.AddReasoner(engine);

            Statement question = new Statement(hotel, isNear, location2);
            Debug.WriteLine("Euler Says the Question is: " + store.Contains(question));
            #region
            GraphMatch gm = new GraphMatch();
            gm.AddGraphStatement(new Statement(hotel, isNear, location2));
            QueryResultSink sink = new SparqlXmlQuerySink(Console.Out);
            gm.Run(store, sink);
            #endregion
        }

        public static void Test1()
        {
            // Create the instance data

            MemoryStore dataModel = new MemoryStore();

            BNode paris = new BNode("paris");
            BNode orleans = new BNode("orleans");
            BNode chartres = new BNode("chartres");
            BNode amiens = new BNode("amiens");
            BNode blois = new BNode("blois");
            BNode bourges = new BNode("bourges");
            BNode tours = new BNode("tours");
            BNode lemans = new BNode("lemans");
            BNode angers = new BNode("angers");
            BNode nantes = new BNode("nantes");

            Entity oneway = new Entity("http://www.agfa.com/w3c/euler/graph.axiom#oneway");
            Entity path = new Entity("http://www.agfa.com/w3c/euler/graph.axiom#path");

            dataModel.Add(new Statement(paris, oneway, orleans));
            dataModel.Add(new Statement(paris, oneway, chartres));
            dataModel.Add(new Statement(paris, oneway, amiens));
            dataModel.Add(new Statement(orleans, oneway, blois));
            dataModel.Add(new Statement(orleans, oneway, bourges));
            dataModel.Add(new Statement(blois, oneway, tours));
            dataModel.Add(new Statement(chartres, oneway, lemans));
            dataModel.Add(new Statement(lemans, oneway, angers));
            dataModel.Add(new Statement(lemans, oneway, tours));
            dataModel.Add(new Statement(angers, oneway, nantes));

            // Create the inference rules by reading them from a N3 string.

            string rules =
                "@prefix : <http://www.agfa.com/w3c/euler/graph.axiom#>.\n" +
                "\n" +
                "{ ?a :oneway ?b } => { ?a :path ?b } .\n" +
                "{ ?a :path ?b . ?b :path ?c . } => { ?a :path ?c } .\n";

            // Create our question in the form of a statement to test.

            Statement question = new Statement(paris, path, nantes);

            // Create the Euler engine

            Euler engine = new Euler(new N3Reader(new StringReader(rules)));

            // First Method of Inference:
            // Ask the engine whether there is a path from paris to nantes.
            // The Prove method will return a list of proofs, or an empty
            // array if it could not find a proof.

            foreach (Proof p in engine.Prove(dataModel, new Statement[] { question }))
            {
                Console.WriteLine(p.ToString());
            }

            // Second Method of Inference:
            // Apply the engine to the data model and then use the data
            // model's Contains method to see if the statement is "in"
            // the model + reasoning.

            dataModel.AddReasoner(engine);

            Console.WriteLine("Euler Says the Question is: " + dataModel.Contains(question));
        }
    }

    internal static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        private static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}